#pragma once 

#include <memory>
#include <functional>
#include <cstdint>
#include <vector>
#include <unordered_set>
#include <deque>

namespace tmms
{
    namespace network
    {
        using EntryPtr = std::shared_ptr<void>; // 泛化所有定时任务入口,它可以​​安全地存储和传递任何类型的对象指针
        using WheelEntry = std::unordered_set<EntryPtr>;
        using Wheel = std::deque<WheelEntry>;
        using Wheels = std::vector<Wheel>;
        using Func  = std::function<void()>;

        const int KTimingMinute = 60;
        const int KTimingHour = 60*60;
        const int KTimingDay = 60*60*24;

        enum TimingType
        {
            KTimingTypeSecond =0,
            KTimingTypeMinute =1,
            KTimingTypeHour =2,
            KTimingTypeDay =3,
        };

       
        class CallbackEntry
        { //时间轮算法
        public:
            CallbackEntry(const Func &cb):cb_(cb){};
            ~CallbackEntry() //在析构的时候调用析构函数
            {
                if(cb_)
                {
                    cb_();
                }
            }
        private:
            Func cb_;
        };

        using CallbackEntryPtr = std::shared_ptr<CallbackEntry>;

        class TimingWheel
        {//定时任务
        private:
            void InserSecondEntry(uint32_t delay,EntryPtr entryptr);
            void InserMinuteEntry(uint32_t delay,EntryPtr entryptr);
            void InserHourEntry(uint32_t delay,EntryPtr entryptr);
            void InserDayEntry(uint32_t delay,EntryPtr entryptr);
            Wheels wheels_;
            int64_t last_ts_{0};
            uint64_t tick_{0};
        public:
            TimingWheel();
            ~TimingWheel();

            void InserEntry(uint32_t delay,EntryPtr entryptr);
            void OnTimer(int64_t now);
            void PopUp(Wheel &bq);
            void RunAfter(double delay,const Func &cb);
            void RunAfter(double delay,Func &&cb);
            void RunEvery(double interval,const Func &cb );
            void RunEvery(double interval,Func &&cb );
        };
    }
}


